home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D GFX
/
3D GFX.iso
/
amiutils
/
i_l
/
irit5
/
irit
/
irit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-12-30
|
30KB
|
720 lines
/*****************************************************************************
* Main module of "Irit" - the 3d (not only polygonal) solid modeller. *
******************************************************************************
* Usage: *
* Irit [-t] [-z] *
* *
* Written by: Gershon Elber Ver 3.0, Apr. 1990 *
*****************************************************************************/
#include <stdio.h>
#include <signal.h>
#include <string.h>
#include "program.h"
#include "config.h"
#include "ctrl-brk.h"
#include "dosintr.h"
#include "inptprsg.h"
#include "iritprsr.h"
#include "irit_soc.h"
#include "objects.h"
#include "windows.h"
#include "iritgrap.h"
#include "bool_lib.h"
#include "trim_lib.h"
#include "triv_lib.h"
#include "symb_lib.h"
#ifdef __WINNT__
#include <direct.h>
#endif /* __WINNT__ */
#ifdef DJGCC
#include "intr_lib.h"
#include "intr_gr.h"
#endif /* DJGCC */
#ifdef NO_CONCAT_STR
static char *VersionStr = "Irit Version 5.0, Gershon Elber,\n\
(C) Copyright 1989/90-95 Gershon Elber, Non commercial use only.";
#else
static char *VersionStr = "Irit " VERSION
", Gershon Elber, " __DATE__ ", " __TIME__ "\n"
COPYRIGHT ", Non commercial use only.";
#endif /* NO_CONCAT_STR */
static char *CtrlStr = "Irit [-t] [-z] [file.irt]";
char *GlblHelpFileName = "irit.hlp";
static char
*GlblPrgmHeader = " Irit - the not only polygonal solid modeller";
static char
*GlblCopyRight =
#ifdef DJGCC
COPYRIGHT ", DJGCC " VERSION ", " __DATE__;
#else
#ifdef OS2GCC
COPYRIGHT ", OS2 " VERSION ", " __DATE__;
#else
#ifdef AMIGA
COPYRIGHT ", Amiga " VERSION ", " __DATE__;
#else
#ifdef NO_CONCAT_STR
"(C) Copyright 1989/90-95 Gershon Elber, Unix Version 5.0";
#else
COPYRIGHT ", Unix " VERSION;
#endif /* NO_CONCAT_STR */
#endif /* AMIGA */
#endif /* OS2GCC */
#endif /* DJGCC */
static char
*GlblAuthorName = " Written by Gershon Elber";
IPObjectStruct
*GlblObjList = NULL; /* All objects defined on system. */
char GlblCrntWorkingDir[LINE_LEN]; /* Save start CWD to recover on exit. */
FILE
*GlblLogFile = NULL;
jmp_buf GlblLongJumpBuffer; /* Used in error recovery. */
int
#ifdef DJGCC /* Defaults for intr_lib. */
GlblWindowFrameWidth = 8,
GlblViewFrameColor = INTR_COLOR_RED,
GlblViewBackColor = INTR_COLOR_BLACK,
GlblTransFrameColor = INTR_COLOR_GREEN,
GlblTransBackColor = INTR_COLOR_BLACK,
GlblStatusFrameColor = INTR_COLOR_MAGENTA,
GlblStatusBackColor = INTR_COLOR_BLACK,
GlblInputFrameColor = INTR_COLOR_YELLOW,
GlblInputBackColor = INTR_COLOR_BLACK,
GlblDrawHeader = FALSE,
GlblSmoothTextScroll = TRUE,
GlblIntrSaveMethod = INTR_SAVE_DISK,
GlblMouseSensitivity = 10, /* Sensitivity control of mouse device. */
GlblJoystickExists = FALSE,
#endif /* DJGCC */
GlblDisplayDeviceInput = -1,
GlblDisplayDeviceOutput = -1,
GlblInterpProd = TRUE,
GlblLoadColor = DEFAULT_LOAD_COLOR,
GlblPrimColor = DEFAULT_PRIM_COLOR,
GlblDoGraphics = TRUE,/* Control if running in graphics/text mode. */
GlblFatalError = FALSE, /* True if disaster in system - must quit! */
GlblPrintLogFile = FALSE, /* If TRUE everything goes to log file. */
GlblPointLenAux = IG_POINT_DEFAULT_LENGTH;
RealType
GlblPointLen = 0.02; /* Scaler for point if drawn. */
char
#ifdef DJGCC /* Defaults for intr_lib. */
*GlblViewWndwPos = "0.02, 0.02, 0.72, 0.66",
*GlblTransWndwPos = "0.75, 0.02, 0.98, 0.66",
*GlblStatusWndwPos = "0.75, 0.02, 0.98, 0.66",
*GlblInputWndwPos = "0.04, 0.7, 0.98, 0.98",
*GlblIntrSaveDisk = "c:\\",
#endif /* DJGCC */
*GlblStartFileName = "",
*GlblLogFileName = "",
#ifdef DOUBLE
*GlblFloatFormat = "%-8.6lg";
#else
*GlblFloatFormat = "%-8.6g";
#endif /* DOUBLE */
static ConfigStruct SetUp[] =
{
#ifdef DJGCC
{ "Joystick", "", (VoidPtr) &GlblJoystickExists, SU_BOOLEAN_TYPE },
{ "MouseSensitivity", "", (VoidPtr) &GlblMouseSensitivity,SU_INTEGER_TYPE },
{ "WndwWidth", "", (VoidPtr) &GlblWindowFrameWidth,SU_INTEGER_TYPE },
{ "WndwHeader", "", (VoidPtr) &GlblDrawHeader, SU_BOOLEAN_TYPE },
{ "WndwSmthTxtScrl", "", (VoidPtr) &GlblSmoothTextScroll,SU_BOOLEAN_TYPE },
{ "WndwViewClr", "", (VoidPtr) &GlblViewFrameColor, SU_INTEGER_TYPE },
{ "WndwTransClr", "", (VoidPtr) &GlblTransFrameColor,SU_INTEGER_TYPE },
{ "WndwInputClr", "", (VoidPtr) &GlblInputFrameColor,SU_INTEGER_TYPE },
{ "WndwViewPos", "", (VoidPtr) &GlblViewWndwPos, SU_STRING_TYPE },
{ "WndwTransPos", "", (VoidPtr) &GlblStatusWndwPos, SU_STRING_TYPE },
{ "WndwInputPos", "", (VoidPtr) &GlblInputWndwPos, SU_STRING_TYPE },
{ "WndwBackSave", "", (VoidPtr) &GlblIntrSaveMethod, SU_INTEGER_TYPE },
{ "WndwBackSavePath", "", (VoidPtr) &GlblIntrSaveDisk, SU_STRING_TYPE },
#endif /* DJGCC */
{ "DoGraphics", "-t", (VoidPtr) &GlblDoGraphics, SU_BOOLEAN_TYPE },
{ "InterpProd", "", (VoidPtr) &GlblInterpProd, SU_BOOLEAN_TYPE },
{ "PointLength", "", (VoidPtr) &GlblPointLenAux, SU_INTEGER_TYPE },
{ "LoadColor", "", (VoidPtr) &GlblLoadColor, SU_INTEGER_TYPE },
{ "PrimColor", "", (VoidPtr) &GlblPrimColor, SU_INTEGER_TYPE },
{ "StartFile", "", (VoidPtr) &GlblStartFileName, SU_STRING_TYPE },
{ "LogFile", "", (VoidPtr) &GlblLogFileName, SU_STRING_TYPE },
{ "FloatFrmt", "", (VoidPtr) &GlblFloatFormat, SU_STRING_TYPE },
};
#define NUM_SET_UP (sizeof(SetUp) / sizeof(ConfigStruct))
static void Interact(void);
static void PrintInptPrsrError(void);
/*****************************************************************************
* DESCRIPTION: M
* Main module of IRIT - Read command line and do what is needed... M
* *
* PARAMETERS: M
* argc, argv: Command line. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* main M
*****************************************************************************/
void main(int argc, char **argv)
{
char *FullPathStartFileName;
IritCPUTime(TRUE); /* Reset the clock. */
Config("irit", SetUp, NUM_SET_UP); /* Read config. file if exists. */
while (argc >= 2) {
if (strncmp(argv[1], "-z", 2) == 0) {
fprintf(stderr, "\n%s\n\nUsage: %s\n", VersionStr, CtrlStr);
ConfigPrint(SetUp, NUM_SET_UP);
exit(0);
}
else if (strncmp(argv[1], "-t", 2) == 0) {
GlblDoGraphics = FALSE;
}
else {
break;
}
argv++;
argc--;
}
getcwd(GlblCrntWorkingDir, LINE_LEN - 1);
SetUpCtrlBrk(); /* Set up control break trap routine (int 1bh). */
signal(SIGFPE, DefaultFPEHandler); /* Will trap floating point errors. */
BspMultInterpFlag(GlblInterpProd);
IritPrsrSetFloatFormat(GlblFloatFormat);
IritPrsrSetFlattenObjects(FALSE);
IritPrsrSetPolyListCirc(TRUE);
/* Print some copyright messages: */
WndwInputWindowPutStr(GlblPrgmHeader);
WndwInputWindowPutStr(GlblCopyRight);
WndwInputWindowPutStr(GlblAuthorName);
SetUpPredefObjects(); /* Prepare the predefined objects. */
/* Execute the file specified in the command line if was one: */
if (argc == 2)
FileInclude(argv[1]);
/* Execute the start up file first by inserting it to the include stack. */
if ((int) strlen(GlblStartFileName) > 0 &&
(FullPathStartFileName = searchpath(GlblStartFileName)) != NULL)
FileInclude(FullPathStartFileName);
Interact(); /* Go and do some real work... */
IritExit(0);
}
/*****************************************************************************
* DESCRIPTION: *
* Interact - the main read/eval/print routine. This routine reads data from *
* standart input and execute it "forever" (using Input Parser). *
* Note exit from this program is controled by input parser itself. *
* *
* PARAMETERS: *
* None *
* *
* RETURN VALUE: *
* void *
*****************************************************************************/
static void Interact(void)
{
/* setjmp return 0 on first install time. Will return 1 if error is */
/* recoverable, 2 if cannt continue - must quit the program now. */
switch (setjmp(GlblLongJumpBuffer)) { /* Used in error recovery. */
case 0:
case 1:
while (TRUE) {
if (!InputParser()) /* Print the error message. */
PrintInptPrsrError();
}
case 2:
WndwInputWindowPutStr("Press return to die...");
getchar();
break;
}
}
/*****************************************************************************
* DESCRIPTION: M
* Modifies the state of the IRIT solid modeller. M
* *
* PARAMETERS: M
* Name: Name of state variable. M
* Data: New value of state variable. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* SetIritState M
*****************************************************************************/
void SetIritState(char *Name, IPObjectStruct *Data)
{
if (stricmp(Name, "InterpProd") == 0) {
if (IP_IS_NUM_OBJ(Data))
BspMultInterpFlag(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "DebugFunc") == 0) {
if (IP_IS_NUM_OBJ(Data))
InptPrsrDebugFuncLevel(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "EchoSource") == 0) {
if (IP_IS_NUM_OBJ(Data))
InptPrsrEchoSource(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "FloatFrmt") == 0) {
if (IP_IS_STR_OBJ(Data)) {
strcpy(GlblFloatFormat, Data -> U.Str);
IritPrsrSetFloatFormat(GlblFloatFormat);
}
else
WndwInputWindowPutStr("String state value expected");
}
else if (stricmp(Name, "InterCrv") == 0) {
if (IP_IS_NUM_OBJ(Data))
BoolSetOutputInterCurve(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "Coplanar") == 0) {
if (IP_IS_NUM_OBJ(Data))
BoolSetHandleCoplanarPoly(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "PolySort") == 0) {
if (IP_IS_NUM_OBJ(Data))
BoolSetPolySortAxis(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "DumpLevel") == 0) {
if (IP_IS_NUM_OBJ(Data))
SetDumpLevel(REAL_TO_INT(Data -> U.R));
else
WndwInputWindowPutStr("Numeric state value expected");
}
else if (stricmp(Name, "TrimCrvs") == 0) {
if (IP_IS_NUM_OBJ(Data)) {
TrimSetEuclidComposedFromUV(Data -> U.R <= 0);
TrimSetTrimCrvLinearApprox((int) (fabs(Data -> U.R)), FALSE);
}
else
WndwInputWindowPutStr("Numeric state value expected");
}
}
/*****************************************************************************
* DESCRIPTION: *
* Routine to query (and print) the errors found by InputParser. *
* *
* PARAMETERS: *
* None *
* *
* RETURN VALUE: *
* void *
*****************************************************************************/
static void PrintInptPrsrError(void)
{
InptPrsrEvalErrType ErrorNum;
char *ErrorMsg, *p;
char Line[LINE_LEN_LONG];
if ((ErrorNum = InptPrsrParseError(&ErrorMsg)) != IPE_NO_ERR) {/*Prsr err*/
sprintf(Line, "Parsing Error: ");
p = &Line[strlen(Line)];
switch (ErrorNum) {
case IP_ERR_WRONG_SYNTAX:
sprintf(p, "Wrong syntax\n");
break;
case IP_ERR_PARAM_EXPECT:
sprintf(p, "Parameter Expected\n");
break;
case IP_ERR_ONE_OPERAND:
case IP_ERR_TWO_OPERAND:
sprintf(p, "Wrong # of operands - %s\n", ErrorMsg);
break;
case IP_ERR_STACK_OV:
sprintf(p, "Internal Stack OverFlow at - %s\n", ErrorMsg);
break;
case IP_ERR_PARAM_MATCH:
sprintf(p, "Parenthesis mismatch - %s\n", ErrorMsg);
break;
case IP_ERR_UNDEF_TOKEN:
sprintf(p, "Undefined token - %s\n", ErrorMsg);
break;
case IP_ERR_UNDEF_FUNC:
sprintf(p, "Undefined function - %s\n", ErrorMsg);
break;
case IP_ERR_NAME_TOO_LONG:
sprintf(p, "Object name too long - %s\n", ErrorMsg);
break;
case IP_ERR_PARAM_FUNC:
sprintf(p, "Parameters expected in func %s\n", ErrorMsg);
break;
case IP_ERR_NO_PARAM_FUNC:
sprintf(p, "No Parameters expected in func %s\n", ErrorMsg);
break;
case IP_ERR_STR_TOO_LONG:
sprintf(p, "String too long - %s\n", ErrorMsg);
break;
default:
sprintf(p, "Undefined error %d", ErrorNum);
break;
}
WndwInputWindowPutStr(Line);
return;
}
if ((ErrorNum = InptPrsrEvalError(&ErrorMsg)) != IPE_NO_ERR) {/*Eval err.*/
sprintf(Line, "Eval Error: ");
p = &Line[strlen(Line)];
switch (ErrorNum) {
case IE_ERR_FATAL_ERROR:
sprintf(p, "Fatal error - %s\n", ErrorMsg);
break;
case IE_ERR_DIV_BY_ZERO:
sprintf(p, "Division by zero - %s\n", ErrorMsg);
break;
case IE_ERR_NO_OBJ_METHOD:
sprintf(p, "No such method for object - %s\n", ErrorMsg);
break;
case IE_ERR_TYPE_MISMATCH:
sprintf(p, "Parameter type mismatch - %s\n",
ErrorMsg);
break;
case IE_ERR_ASSIGN_LEFT_OP:
sprintf(p, "Lval is not a parameter - %s\n", ErrorMsg);
break;
case IE_ERR_MIXED_OBJ:
sprintf(p, "Mixed types in expression - %s\n", ErrorMsg);
break;
case IE_ERR_IP_OBJ_UNDEFINED:
sprintf(p, "No such object defined - %s\n", ErrorMsg);
break;
case IE_ERR_NO_ASSIGNMENT:
sprintf(p, "Assignment was expected\n");
break;
case IE_ERR_FP_ERROR:
sprintf(p, "Floating Point Error - %s\n", ErrorMsg);
break;
case IE_ERR_NUM_PRM_MISMATCH:
sprintf(p, "Number of func. param. mismatch - %s\n", ErrorMsg);
break;
case IE_ERR_MAT_POWER:
sprintf(p, "Wrong range or not exists, operator - %s\n", ErrorMsg);
break;
case IE_ERR_FREE_SIMPLE:
sprintf(p, "Free only geometric objects - %s\n", ErrorMsg);
break;
case IE_ERR_MODIF_ITER_VAR:
sprintf(p, "Iteration var. type modified or freed - %s\n", ErrorMsg);
break;
case IE_ERR_BOOLEAN_ERR:
sprintf(p, "Geometric Boolean operation error - %s\n", ErrorMsg);
break;
case IE_ERR_OUT_OF_RANGE:
sprintf(p, "Out of range.\n");
break;
case IE_ERR_DATA_PRSR_ERROR:
sprintf(p, "%s", ErrorMsg);
break;
case IE_ERR_USER_FUNC_NO_RETVAL:
sprintf(p, "User defined function \"%s\" has no returned value\n",
ErrorMsg);
break;
case IE_ERR_INCOMPARABLE_TYPES:
sprintf(p, "Incomparable object types found");
break;
case IE_ERR_ONLYEQUALITY_TEST:
sprintf(p, "Only equality or non equality test is valid for these objects");
break;
case IE_ERR_IF_HAS_NO_COND:
sprintf(p, "Condition of if clause is illegal");
break;
case IE_ERR_IP_USERFUNC_DUP_VAR:
sprintf(p, "Duplicated variable, %s", ErrorMsg);
break;
default:
sprintf(p, "Undefined error %d\n", ErrorNum);
break;
}
WndwInputWindowPutStr(Line);
return;
}
}
/*****************************************************************************
* DESCRIPTION: M
* IRIT Exit routine. Error code of zero. M
* *
* PARAMETERS: M
* None *
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* IritExit0 M
*****************************************************************************/
void IritExit0(void)
{
IritExit(0);
}
/*****************************************************************************
* DESCRIPTION: M
* IRIT Exit routine. M
* *
* PARAMETERS: M
* ExitCode: Exit code. *
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* IritExit M
*****************************************************************************/
void IritExit(int ExitCode)
{
if (GlblDoGraphics) {
WndwViewExit();
}
ClientCloseAll(TRUE);
chdir(GlblCrntWorkingDir); /* Recover original directory before exit. */
if (GlblPrintLogFile)
fclose(GlblLogFile); /* Close log file if was open. */
exit(ExitCode);
}
/*****************************************************************************
* DESCRIPTION: M
* Traps Cagd_lib errors right here. Call back function of cagd_lib. M
* *
* PARAMETERS: M
* ErrID: Error number in cagd_lib library. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* CagdFatalError M
*****************************************************************************/
void CagdFatalError(CagdFatalErrorType ErrID)
{
char Line[LINE_LEN],
*ErrorMsg = CagdDescribeError(ErrID);
sprintf(Line, "CAGD_LIB: %s", ErrorMsg);
WndwInputWindowPutStr(Line);
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1); /* Go back to main loop directly. */
}
/*****************************************************************************
* DESCRIPTION: M
* Traps Symb_lib errors right here. Call back function of symb_lib. M
* *
* PARAMETERS: M
* ErrID: Error number in symb_lib library. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* SymbFatalError M
*****************************************************************************/
void SymbFatalError(SymbFatalErrorType ErrID)
{
char Line[LINE_LEN],
*ErrorMsg = SymbDescribeError(ErrID);
sprintf(Line, "SYMB_LIB: %s", ErrorMsg);
WndwInputWindowPutStr(Line);
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1); /* Go back to main loop directly. */
}
/*****************************************************************************
* DESCRIPTION: M
* Traps Trim_lib errors right here. Call back function of trim_lib. M
* *
* PARAMETERS: M
* ErrID: Error number in trim_lib library. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* TrimFatalError M
*****************************************************************************/
void TrimFatalError(TrimFatalErrorType ErrID)
{
char Line[LINE_LEN],
*ErrorMsg = TrimDescribeError(ErrID);
sprintf(Line, "TRIM_LIB: %s", ErrorMsg);
WndwInputWindowPutStr(Line);
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1); /* Go back to main loop directly. */
}
/*****************************************************************************
* DESCRIPTION: M
* Traps Triv_lib errors right here. Call back function of triv_lib. M
* *
* PARAMETERS: M
* ErrID: Error number in triv_lib library. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* TrivFatalError M
*****************************************************************************/
void TrivFatalError(TrivFatalErrorType ErrID)
{
char Line[LINE_LEN],
*ErrorMsg = TrivDescribeError(ErrID);
sprintf(Line, "TRIV_LIB: %s", ErrorMsg);
WndwInputWindowPutStr(Line);
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1); /* Go back to main loop directly. */
}
/*****************************************************************************
* DESCRIPTION: M
* Prints IRIT's fatal error message and go back to cursor mode. M
* *
* PARAMETERS: M
* ErrorMsg: Error message to print out. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* IritPrsrFatalError M
*****************************************************************************/
void IritFatalError(char *ErrorMsg)
{
if (ErrorMsg != NULL) {
WndwInputWindowPutStr("Fatal error occured, please report it:");
WndwInputWindowPutStr(ErrorMsg);
}
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1); /* Go back to main loop directly. */
}
/*****************************************************************************
* DESCRIPTION: M
* Prints IRIT parser's fatal error message and go back to cursor mode. M
* *
* PARAMETERS: M
* ErrorMsg: Error message to print out. M
* *
* RETURN VALUE: M
* void M
* M
* KEYWORDS: M
* IritPrsrFatalError M
*****************************************************************************/
void IritPrsrFatalError(char *ErrorMsg)
{
if (ErrorMsg != NULL) {
WndwInputWindowPutStr(ErrorMsg);
}
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1); /* Go back to main loop directly. */
}
/*****************************************************************************
* DESCRIPTION: M
* Called from the floating point package in case of fatal floating point M
* error. M
* Prints error message and long jumps to main loop. M
* Default FPE handler - must be reset after redirected to other module. M
* *
* PARAMETERS: M
* Type: Of floating point error. M
* *
* RETURN VALUE: M
* void M
* *
* KEYWORDS: M
* DefaultFPEHandler M
*****************************************************************************/
void DefaultFPEHandler(int Type)
{
char Line[LINE_LEN];
sprintf(Line, "Floating point error %d.", Type);
WndwInputWindowPutStr(Line);
FlushToEndOfExpr(TRUE);
longjmp(GlblLongJumpBuffer, 1);
}
#ifdef DEBUG
/*****************************************************************************
* DESCRIPTION: *
* Dummy function to link at debugging time. *
* *
* PARAMETERS: *
* *
* RETURN VALUE: *
* void *
* *
* KEYWORDS: *
*****************************************************************************/
void DummyLinkCagdDebug(void)
{
IritPrsrDbg();
}
#endif /* DEBUG */